#pragma once

#include "Mathematics.h"
#include "CameraManager.h"

class Pipeline {
public:
	inline Pipeline () {
		_transformation.setIdentity();
		_rotation.setAll(0.f);
		_scale.setAll(1.f);
		_translation.setAll(0.f);
	}

	inline void scale(fp32 x_scale, fp32 y_scale, fp32 z_scale) {
		_scale.set(x_scale, y_scale, z_scale);
	}

	inline void translate(fp32 x_pos, fp32 y_pos, fp32 z_pos) {
		_translation.set(x_pos, y_pos, z_pos);
	}

	// Argument - radians!!!
	inline void rotate(fp32 x_ang, fp32 y_ang, fp32 z_ang) {
		_rotation.set(x_ang, y_ang, z_ang);
	}

	// No need in this - always use default for now
	//inline void setPerspectiveProjection(u32 width, u32 height, fp32 near_v, fp32 far_v, fp32 fov) {
	//	_perspective_projection.width = width;
	//	_perspective_projection.height = height;
	//	_perspective_projection.near_v = near_v;
	//	_perspective_projection.far_v = far_v;
	//	_perspective_projection.fov = fov;
	//}

	inline Matrix_4x4 &getFinalTransform() const {
		Matrix_4x4 projection, translation, rotation, scale;
		projection = Matrix_4x4::projectionMatrix(_perspective_projection);
		translation.translate(_translation);
		rotation.rotate(_rotation);
		scale.scale(_scale);
		_transformation = projection.mulb(CameraManager::instance().cameraRotation()).mulb(CameraManager::instance().cameraTranslation()).mulb(translation).mulb(rotation).mulb(scale);
		return _transformation;
	}

	inline const Vector3f &getTranslation() const {
		return _translation;
	}

private:
	Vector3f _scale;
	Vector3f _rotation;
	Vector3f _translation;
	PerspectiveParams _perspective_projection;
	mutable Matrix_4x4 _transformation;
};